package com.fjh.service.impl;

import com.fjh.domain.SysPermission;
import com.fjh.dto.PermissionDto;
import com.fjh.mapper.SysPermissionMapper;
import com.fjh.service.PermissionService;
import com.fjh.vo.SelectNode;
import com.fjh.vo.TreeNode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private SysPermissionMapper sysPermissionMapper;

    /**
     * 查询所有的树菜单
     * @return
     */
    @Override
    public List<SysPermission> selectAllSysPermission() {
        return sysPermissionMapper.selectAllSysPermission();
    }

    /**
     * 将一个普通的权限集合转化为一棵树
     * @param allData
     * @return
     */
    @Override
    public List<TreeNode> convertTreeNode(List<SysPermission> allData) {
        return convertTreeNodeInner(allData);
    }

    /**
     *
     * @param dto
     * @return
     */
    @Override
    public List<SysPermission> findByPage(PermissionDto dto) {
        List<SysPermission> sysPermissions = sysPermissionMapper.selectByPage(dto);
        return sysPermissions;
    }

    /**
     * 新增
     * @param dto
     * @return
     */
    @Override
    public Boolean addPerms(PermissionDto dto) {
        //1.校验数据
        validate(dto);
        //2属性的copy
        SysPermission sysPermission = new SysPermission();
        BeanUtils.copyProperties(dto,sysPermission);
        //3.默认值的填写
        sysPermission.setSpread(dto.getSpread() == 1 ? Boolean.TRUE : Boolean.FALSE);
        return sysPermissionMapper.insert(sysPermission)>0;
    }

    /**
     * 校验数据
     * @param dto
     */
    private void validate(PermissionDto dto) {
        if (dto.getParentId() == null) {
            throw new IllegalArgumentException("前选择一个父菜单");
        }
        if (dto.getTitle() == null) {
            throw new IllegalArgumentException("权限的名称不能为空");
        }
        // 我必须是目录
        if (dto.getParentId() == 0) {
            if (dto.getType() != 0) {
                throw new IllegalArgumentException("根节点必须为目录");
            }
        }
        // 菜单必须有href
        if (dto.getType() == 1) {
            if (dto.getHref() == null) {
                throw new IllegalArgumentException("菜单必须为地址");
            }
        }
        // 按钮必须有权限的标识
        if (dto.getType() == 2) {
            if (dto.getTag() == null) {
                throw new IllegalArgumentException("按钮必须添加权限的标识");
            }
        }
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public Boolean batchRemove(Integer[] ids) {
        int row = 0;
        for (Integer id : ids) {
            // 1 判断是否有儿子-- 将它看成父亲查询儿子的数量
            Integer count = sysPermissionMapper.selectCountByParentId(id);
            if (count != null && count > 0 ){
                throw  new IllegalArgumentException("子节点不为空,删除所有的子节点后,再执行删除");
            }
            //否则直接删除
            row += sysPermissionMapper.deleteByPrimaryKey(id);
        }
        return row == ids.length;
    }

    /**
     * 修改权限的数据
     * @param dto
     * @return
     */
    @Override
    public Boolean updatePerms(PermissionDto dto) {
        // 菜单数据的额修改,比较特殊
        //菜单数据的修改 : 只能修改: 名称 标识, 图标 排序 地址  是否展开
        // 不能修改父菜单以及它的类型
        // 校验数据
        Integer id = dto.getId();
        SysPermission sysPermissionDb = sysPermissionMapper.selectByPrimaryKey(id);
        if (!sysPermissionDb.getParentId().equals(dto.getParentId())) {
            throw new IllegalArgumentException("父菜单不能被修改");
        }
        if (!sysPermissionDb.getType().equals(dto.getType())) {
            throw new IllegalArgumentException("菜单的类型不能被修改");
        }
        // 属性copy
        SysPermission sysPermission = new SysPermission();
        BeanUtils.copyProperties(dto, sysPermission);
        sysPermission.setSpread(dto.getSpread() == 1 ? true : false);
        return sysPermissionMapper.updateByPrimaryKey(sysPermission) > 0;
    }

    /**
     * 获取当前角色的权限id集合
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> getPermsByRoleId(Integer roleId) {
        return sysPermissionMapper.selectPermIdByRoleId(roleId);
    }

    /**
     * 给角色分配权限
     * @param roleId
     * @param permsIds
     * @return
     */
    @Override
    @Transactional
    public Boolean assign(Integer roleId, Integer[] permsIds) {
        //删除旧的权限
        int delete = sysPermissionMapper.deleteByRoleIds(roleId);
        //新增新的值
        int add = sysPermissionMapper.insertNewRole(roleId,permsIds);
        return delete>=0;
    }

    /**
     * 将 权限数据转化为下拉框的选择数据
     * @param sysPermissions
     * @return
     */
    @Override
    public List<SelectNode> convertSelectNode(List<SysPermission> sysPermissions) {
        Map<Integer, SelectNode> selectRoots = new HashMap<>();
        for (SysPermission sysPermission: sysPermissions ){
            SelectNode selectNode = new SelectNode();
            BeanUtils.copyProperties(sysPermission,selectNode);
            selectRoots.put(sysPermission.getId(), selectNode);
        }
        List<SelectNode> root = new ArrayList<>();
        selectRoots.forEach((id,node)->{
            SelectNode selectNode = selectRoots.get(node.getParentId());
            if (selectNode != null){
                selectNode.getChild().add(node);
            }else {
                root.add(node);
            }
        });
        return root;
    }

    @Override
    public List<SysPermission> getPermsByUserIdAndType(Integer id, List<Integer> types) {
        return sysPermissionMapper.selectPermsByUserIdAndType(id,types);
    }

    /**
     * 将权限转化为一棵树
     * @param allData
     * @return
     */
    public List<TreeNode> convertTreeNodeInner(List<SysPermission> allData) {
        //id<--->TreeNode集合
        Map<Integer, TreeNode> idTreeMapping = new HashMap<>();
        for (SysPermission allDayum : allData) {
            TreeNode treeNode = new TreeNode();
            BeanUtils.copyProperties(allDayum,treeNode);
            //            treeNode.setId(allDatum.getId());
//            treeNode.setTitle(allDatum.getTitle());
//            treeNode.setParentId(allDatum.getParentId());
            treeNode.setOpenType(treeNode.getType() == 1? "_iframe" : "");
            idTreeMapping.put(allDayum.getId(), treeNode);
        }
        List<TreeNode> roots = new ArrayList<>();
        //使用父亲的id给父亲添加元素
        idTreeMapping.forEach((id,node)->{
            //获取父亲的id
            Integer parentId = node.getParentId();
            TreeNode treeNode = idTreeMapping.get(parentId);
            if (treeNode != null){
                treeNode.getChildren().add(node);
            }else {
                //没有父亲
                roots.add(node);
            }
        });
        return roots;
    }
}
